package com.lemonPiggy.message.controller;

import java.util.*;
import java.io.IOException;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.alibaba.fastjson.JSONObject;
import com.lemonPiggy.message.domain.MessageAnnouncement;
import com.lemonPiggy.message.domain.MessageAnnouncementSend;
import com.lemonPiggy.message.util.oConvertUtils;
import com.lemonPiggy.message.websocket.WebSocket;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.enums.CommonSendStatus;
import com.ruoyi.common.core.enums.WebsocketConst;
import com.ruoyi.common.core.utils.SecurityUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.system.api.RemoteActivitiService;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import com.lemonPiggy.message.service.IMessageAnnouncementSendService;
import com.lemonPiggy.message.service.IMessageAnnouncementService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.common.security.annotation.PreAuthorize;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.utils.poi.ExcelUtil;
import com.ruoyi.common.core.web.page.TableDataInfo;

/**
 * 系统通告Controller
 * 
 * @author ruoyi
 * @date 2021-08-17
 */
@RestController
@RequestMapping("/announcement")
@Slf4j
public class MessageAnnouncementController extends BaseController {
    @Autowired
    private IMessageAnnouncementService messageAnnouncementService;
    @Autowired
    private IMessageAnnouncementSendService messageAnnouncementSendService;
    @Resource
    private WebSocket webSocket;
    @Autowired
    private RemoteUserService remoteUserService;
    @Autowired
    private RemoteActivitiService remoteActivitiService;

    /**
     * 查询系统通告列表
     */
    @PreAuthorize(hasPermi = "system:announcement:list")
    @GetMapping("/list")
    public TableDataInfo list(MessageAnnouncement messageAnnouncement) {
        startPage();
        List<MessageAnnouncement> list = messageAnnouncementService.selectMessageAnnouncementList(messageAnnouncement);
        return getDataTable(list);
    }

    /**
     * 导出系统通告列表
     */
    @PreAuthorize(hasPermi = "system:announcement:export")
    @Log(title = "系统通告", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, MessageAnnouncement messageAnnouncement) throws IOException {
        List<MessageAnnouncement> list = messageAnnouncementService.selectMessageAnnouncementList(messageAnnouncement);
        ExcelUtil<MessageAnnouncement> util = new ExcelUtil<MessageAnnouncement>(MessageAnnouncement.class);
        util.exportExcel(response, list, "系统通告数据");
    }

    /**
     * 获取系统通告详细信息
     */
    @PreAuthorize(hasPermi = "system:announcement:query")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") String id) {
        return AjaxResult.success(messageAnnouncementService.selectMessageAnnouncementById(id));
    }

    /**
     * 新增系统通告
     */
    @PreAuthorize(hasPermi = "system:announcement:add")
    @Log(title = "系统通告", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody @Valid MessageAnnouncement messageAnnouncement) {
        return toAjax(messageAnnouncementService.insertMessageAnnouncement(messageAnnouncement));
    }

    /**
     * 修改系统通告
     */
    @PreAuthorize(hasPermi = "system:announcement:edit")
    @Log(title = "系统通告", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody MessageAnnouncement messageAnnouncement) {
        return toAjax(messageAnnouncementService.updateMessageAnnouncement(messageAnnouncement));
    }

    /**
     * 删除系统通告
     */
    @PreAuthorize(hasPermi = "system:announcement:remove")
    @Log(title = "系统通告", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable String[] ids) {
        return toAjax(messageAnnouncementService.deleteMessageAnnouncementByIds(ids));
    }

    /**
     * @功能：补充用户数据，并返回系统消息
     * @return
     */
    @GetMapping("/listByUser")
    public R  <Map<String,Object>> listByUser() {
        SysUser lu=remoteUserService.getUserInfoById(SecurityUtils.getUserId()).getData().getSysUser();
        Long userId =lu.getUserId();
        startPage();
//        R<Map<String, Object>> result = new R<Map<String, Object>>();
//        SysUser sysUser = new SysUser();
        // 1.将系统消息补充到用户通告阅读标记表中
        MessageAnnouncement ma=new MessageAnnouncement();
        ma.setSendStatus("1");
        ma.setMsgType("ALL");
        ma.setDelFlag("0");

//        ma.setEndTime(createTime);
        //查询出 发布状态为1 通告类型对象为ALL  删除状态为0 的id 并且不属于 查询出的通告id
        List<MessageAnnouncement> announcements = messageAnnouncementService.selectMessageAnnouncementListQuery(ma,userId);
        if (announcements.size() > 0) {
            for (int i = 0; i < announcements.size(); i++) {
                //因为websocket没有判断是否存在这个用户，要是判断会出现问题，故在此判断逻辑
                MessageAnnouncementSend messageAnnouncementSend = new MessageAnnouncementSend();
                //设置消息发送表中的通告id为 查询出来的通告信息id
                messageAnnouncementSend.setAnntId(announcements.get(i).getId());
                //设置消息发送表中的用户id为当前用户id
                messageAnnouncementSend.setUserId(userId + "");
                //查询出已经设置的消息发送表中的信息。
                List<MessageAnnouncementSend> list = messageAnnouncementSendService.selectMessageAnnouncementSendList(messageAnnouncementSend);
                if (list.size()==0) {
                    MessageAnnouncementSend announcementSend = new MessageAnnouncementSend();
                    announcementSend.setAnntId(announcements.get(i).getId());
                    announcementSend.setUserId(userId + "");
                    announcementSend.setReadFlag("0");
                    announcementSend.setCreateBy(lu.getUserName());
                    messageAnnouncementSendService.insertMessageAnnouncementSend(announcementSend);
                }
            }
        }
        List<MessageAnnouncement> messageAnnouncements2 = messageAnnouncementService.querySysCementPageByUserIdALL(userId, "1");
        List<MessageAnnouncement> messageAnnouncements3 = messageAnnouncementService.querySysCementPageByUserIdALL(userId, "2");
//          2.查询用户未读的系统消息
            List<MessageAnnouncement> messageAnnouncements = messageAnnouncementService.querySysCementPageByUserId(userId, "1");//通知公告消息
            List<MessageAnnouncement> messageAnnouncements1 = messageAnnouncementService.querySysCementPageByUserId(userId, "2");//系统消息
            Map<String, Object> sysMsgMap = new HashMap<String, Object>();
            sysMsgMap.put("sysMsgList", messageAnnouncements);
            sysMsgMap.put("sysMsgTotal", messageAnnouncements2.size());
            sysMsgMap.put("anntMsgList", messageAnnouncements1);
            sysMsgMap.put("anntMsgTotal", messageAnnouncements3.size());
            return R.ok(sysMsgMap);
        }


    /**
     *	 更新发布操作
     * @param id
     * @return
     */
    @GetMapping(value = "/doReleaseData/{id}")
    public R<MessageAnnouncement> doReleaseData(@PathVariable("id") String id) {
        R<MessageAnnouncement> result = new R<MessageAnnouncement>();
        MessageAnnouncement messageAnnouncement = messageAnnouncementService.selectMessageAnnouncementById(id);
        if(messageAnnouncement==null) {
            result.setMsg("未找到对应实体");
        }else {
            messageAnnouncement.setSendStatus(CommonSendStatus.PUBLISHED_STATUS_1);//发布中
            messageAnnouncement.setSendTime(new Date());
            messageAnnouncement.setSender(SecurityUtils.getUsername());
            int ok = messageAnnouncementService.updateMessageAnnouncement(messageAnnouncement);
            if(ok>0) {
                result.setMsg("该系统通知发布成功");
                if(messageAnnouncement.getMsgType().equals("ALL")) {
                    JSONObject obj = new JSONObject();
                    obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
                    obj.put(WebsocketConst.MSG_ID, messageAnnouncement.getId());
                    obj.put(WebsocketConst.MSG_TXT, messageAnnouncement.getTitile());
                    webSocket.sendMessage(obj.toJSONString());
                }else {
                    // 2.插入用户通告阅读标记表记录
                    String userId = messageAnnouncement.getUserIds();
                    String[] userIds = userId.split(",");
                    String anntId = messageAnnouncement.getId();
                    Date refDate = new Date();
                    JSONObject obj = new JSONObject();
                    obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
                    obj.put(WebsocketConst.MSG_ID, messageAnnouncement.getId());
                    obj.put(WebsocketConst.MSG_TXT, messageAnnouncement.getTitile());
                    for (int i = 0; i < userIds.length; i++) {
                        MessageAnnouncementSend messageAnnouncementSend = new MessageAnnouncementSend();
                        messageAnnouncementSend.setReadFlag("0");
                        messageAnnouncementSend.setAnntId(anntId);
                        messageAnnouncementSend.setUserId(userIds[i]);
                        messageAnnouncement.setTitile(messageAnnouncement.getTitile());
                        messageAnnouncementSendService.insertMessageAnnouncementSend(messageAnnouncementSend);
                    }
                    webSocket.sendMessage(userIds, obj.toJSONString());
                }
            }
        }
        result.setCode(200);
        return result;
    }

    /**
     *	更新撤销操作
     * @param id
     * @return
     */
    @GetMapping(value = "/doReovkeData/{id}")
    public R<MessageAnnouncement> doReovkeData(@PathVariable("id") String id) {
        R<MessageAnnouncement> result = new R<MessageAnnouncement>();
        MessageAnnouncement messageAnnouncement = messageAnnouncementService.selectMessageAnnouncementById(id);
        if(messageAnnouncement==null) {
            result.setMsg("未找到对应实体");
        }else {
            messageAnnouncement.setSendStatus(CommonSendStatus.REVOKE_STATUS_2);//撤销发布
            messageAnnouncement.setCancelTime(new Date());
            int ok = messageAnnouncementService.updateMessageAnnouncement(messageAnnouncement);
            if(ok>0) {
                result.setMsg("该系统通知撤销成功");
            }
        }
        return result;
    }

    /**
     *同步消息
     * @param anntId
     * @return
     */
    @GetMapping(value = "/syncNotice/{anntId}")
    public R<MessageAnnouncement> syncNotic(@PathVariable(name="anntId") String anntId) {
        R<MessageAnnouncement> result = new R<MessageAnnouncement>();
        JSONObject obj = new JSONObject();
        if(StringUtils.isNotEmpty(anntId)){
            MessageAnnouncement sysAnnouncement = messageAnnouncementService.selectMessageAnnouncementById(anntId);
            if(sysAnnouncement==null) {
                result.setMsg("未找到对应实体");
            }else {
                if(sysAnnouncement.getMsgType().equals("ALL")) {
                    obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
                    obj.put(WebsocketConst.MSG_ID, sysAnnouncement.getId());
                    obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
                    webSocket.sendMessage(obj.toJSONString());
                }else {
                    // 2.插入用户通告阅读标记表记录
                    String userId = sysAnnouncement.getUserIds();
                    if(oConvertUtils.isNotEmpty(userId)){
                        String[] userIds = userId.split(",");
                        obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
                        obj.put(WebsocketConst.MSG_ID, sysAnnouncement.getId());
                        obj.put(WebsocketConst.MSG_TXT, sysAnnouncement.getTitile());
                        webSocket.sendMessage(userIds, obj.toJSONString());
                    }
                }
            }
        }else{
            obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_TOPIC);
            obj.put(WebsocketConst.MSG_TXT, "批量设置已读");
            webSocket.sendMessage(obj.toJSONString());
        }
        return result;
    }

    /**
     * 提醒有即将到期的工作
     */
    @Log(title = "提醒有即将到期的工作", businessType = BusinessType.INSERT)
    @GetMapping(value = "/activitiReminderMessage/{hour}")
    public R activitiReminderMessage(@PathVariable("hour") Integer hour) {
        //查找所有需要提醒的用户
        Map<String,Set<String>> remoteMap=remoteActivitiService.activitiReminder(hour).getData();
        if(null==remoteMap){
            return R.ok("没有需要提醒的工作");
        }
        Set<String> rset=remoteMap.get("roleSet");//取出角色
        Set<String> uset=remoteMap.get("userSet");//取出用户
        Set<String> reset=new HashSet<>();
        for(String userName:uset){
            System.out.println("userName="+userName);
            LoginUser lu=remoteUserService.getUserInfo(userName).getData();
            if(null!=lu.getSysUser().getUserId()){
                reset.add(lu.getSysUser().getUserId()+"");
            }
        }
        for(String roleKey:rset){
            List<SysUser> sulist=remoteUserService.listNoPagingRole(roleKey).getData();
            for(SysUser sysUser:sulist){
                if(null!=sysUser.getUserId()){
                    reset.add(sysUser.getUserId()+"");
                }
            }
        }
        MessageAnnouncement messageAnnouncement=new MessageAnnouncement();
        messageAnnouncement.setTitile("工作提醒");
        messageAnnouncement.setMsgContent("<p>你有待办理的事项！请去查看</p>");
        messageAnnouncement.setMsgCategory("1");
        messageAnnouncement.setPriority("H");
        messageAnnouncement.setMsgType("USER");
        Date today=new Date();
//        SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
//        String messageTime = sdf.format(today);
        messageAnnouncement.setStartTime(today);
        messageAnnouncement.setEndTime(today);
        //====直接发布=====
        messageAnnouncement.setSendStatus(CommonSendStatus.PUBLISHED_STATUS_1);//直接发布
        messageAnnouncement.setSendTime(new Date());
        messageAnnouncement.setSender("system");
        if(reset.size()==0){
            return R.ok("没有需要提醒的工作");
        }
        String userIds="";
        for(String userId:reset){
            userIds=userIds+userId+",";
        }
        userIds=userIds.substring(0,userIds.length()-1);
        messageAnnouncement.setUserIds(userIds);
        long id=messageAnnouncementService.insertMessageAnnouncement(messageAnnouncement);
            if(id>0) {
                    // 2.插入用户通告阅读标记表记录
                String anntId = messageAnnouncement.getId();
                Date refDate = new Date();
                JSONObject obj = new JSONObject();
                obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_USER);
                obj.put(WebsocketConst.MSG_ID, messageAnnouncement.getId());
                obj.put(WebsocketConst.MSG_TXT, messageAnnouncement.getTitile());
                for (String userId:reset) {
                    MessageAnnouncementSend messageAnnouncementSend = new MessageAnnouncementSend();
                    messageAnnouncementSend.setReadFlag("0");
                    messageAnnouncementSend.setAnntId(anntId);
                    messageAnnouncementSend.setUserId(userId);
                    messageAnnouncementSend.setCreateBy("system");
                    messageAnnouncement.setTitile(messageAnnouncement.getTitile());
                    messageAnnouncementSendService.insertMessageAnnouncementSend(messageAnnouncementSend);
                }
                webSocket.sendMessage(reset, obj.toJSONString());
                return R.ok("该系统通知发布成功");
            }
        return R.fail();
    }
}
